package com.yeskery.nut.bind.validator;

import com.yeskery.nut.application.ApplicationType;
import com.yeskery.nut.application.NutWebConfigure;
import com.yeskery.nut.core.AutoDetector;
import com.yeskery.nut.core.AutoDetectorProvider;
import com.yeskery.nut.core.BaseClassNameOnAutoDetector;
import com.yeskery.nut.core.MultiCondition;

/**
 * 基于Hibernate的自定义方法参数验证自动探测器
 * @author sprout
 * @version 1.0
 * 2022-09-01 19:01
 */
public class HibernateMethodParamValidatorAutoDetectorProvider implements AutoDetectorProvider {

    /** Hibernate Validator class名称 */
    private static final String HIBERNATE_VALIDATOR_CLASS_NAME = "org.hibernate.validator.HibernateValidatorFactory";

    /** Jakarta Validator class名称 */
    private static final String JAKARTA_VALIDATION_CLASS_NAME = "jakarta.validation.ValidatorFactory";

    /** Jakarta EL 表达式 class名称 */
    private static final String JAKARTA_EL_CLASS_NAME = "jakarta.el.ExpressionFactory";

    /** Glassfish EL 表达式 class名称 */
    private static final String GLASSFISH_JAKARTA_EL_CLASS_NAME = "com.sun.el.ExpressionFactoryImpl";

    /** Nut Web 相关配置接口 */
    private final NutWebConfigure nutWebConfigure;

    /**
     * 构建基于Hibernate的自定义方法参数验证自动探测器
     * @param nutWebConfigure Nut Web 相关配置接口
     */
    public HibernateMethodParamValidatorAutoDetectorProvider(NutWebConfigure nutWebConfigure) {
        this.nutWebConfigure = nutWebConfigure;
    }

    @Override
    public AutoDetector[] getAutoDetectors() {
        return new AutoDetector[]{new HibernateMethodParamValidatorAutoDetector()};
    }

    /**
     * 是否支持当前应用类型
     * @param applicationType 应用类型
     * @return 是否支持当前应用类型
     */
    public boolean isSupport(ApplicationType applicationType) {
        return ApplicationType.isWebApplicationType(applicationType);
    }

    /**
     * Hibernate的自定义方法参数验证自动探测器
     * @author sprout
     * 2022-09-14 15:38
     */
    private class HibernateMethodParamValidatorAutoDetector extends BaseClassNameOnAutoDetector {

        @Override
        public boolean isSupport(ApplicationType applicationType) {
            return HibernateMethodParamValidatorAutoDetectorProvider.this.isSupport(applicationType);
        }

        @Override
        protected void completeDetect() {
            nutWebConfigure.addMethodParamValidatorHandler(new HibernateMethodParamValidatorHandler());
        }

        @Override
        protected MultiCondition getMultiCondition() {
            return MultiCondition.ALL;
        }

        @Override
        protected String[] getMultiResources() {
            return new String[]{HIBERNATE_VALIDATOR_CLASS_NAME, JAKARTA_VALIDATION_CLASS_NAME, JAKARTA_EL_CLASS_NAME,
                    GLASSFISH_JAKARTA_EL_CLASS_NAME};
        }
    }
}
